package com.zenithmind.user.controller.base;

import com.zenithmind.common.result.Result;
import com.zenithmind.common.result.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;

import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import java.util.stream.Collectors;

/**
 * 基础控制器类
 * 遵循单一职责原则：专门处理通用的控制器功能
 * 遵循开闭原则：提供可扩展的异常处理机制
 */
@Slf4j
public abstract class BaseController {

    /**
     * 处理参数验证异常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Result<Void> handleValidationException(MethodArgumentNotValidException ex) {
        String errorMessage = ex.getBindingResult()
                .getFieldErrors()
                .stream()
                .map(FieldError::getDefaultMessage)
                .collect(Collectors.joining(", "));
        
        log.warn("参数验证失败: {}", errorMessage);
        return Result.fail(ResultCode.INVALID_PARAM.getCode(), errorMessage, null);
    }

    /**
     * 处理绑定异常
     */
    @ExceptionHandler(BindException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Result<Void> handleBindException(BindException ex) {
        String errorMessage = ex.getFieldErrors()
                .stream()
                .map(FieldError::getDefaultMessage)
                .collect(Collectors.joining(", "));
        
        log.warn("参数绑定失败: {}", errorMessage);
        return Result.fail(ResultCode.INVALID_PARAM.getCode(), errorMessage, null);
    }

    /**
     * 处理约束违反异常
     */
    @ExceptionHandler(ConstraintViolationException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Result<Void> handleConstraintViolationException(ConstraintViolationException ex) {
        String errorMessage = ex.getConstraintViolations()
                .stream()
                .map(ConstraintViolation::getMessage)
                .collect(Collectors.joining(", "));
        
        log.warn("约束验证失败: {}", errorMessage);
        return Result.fail(ResultCode.INVALID_PARAM.getCode(), errorMessage, null);
    }

    /**
     * 处理非法参数异常
     */
    @ExceptionHandler(IllegalArgumentException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Result<Void> handleIllegalArgumentException(IllegalArgumentException ex) {
        log.warn("非法参数: {}", ex.getMessage());
        return Result.fail(ResultCode.INVALID_PARAM.getCode(), ex.getMessage(), null);
    }

    /**
     * 处理运行时异常
     */
    @ExceptionHandler(RuntimeException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public Result<Void> handleRuntimeException(RuntimeException ex) {
        log.error("运行时异常: {}", ex.getMessage(), ex);
        return Result.fail(ResultCode.SYSTEM_ERROR.getCode(), "系统内部错误", null);
    }

    /**
     * 处理通用异常
     */
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public Result<Void> handleException(Exception ex) {
        log.error("未知异常: {}", ex.getMessage(), ex);
        return Result.fail(ResultCode.SYSTEM_ERROR.getCode(), "系统异常", null);
    }

    /**
     * 创建成功响应
     */
    protected <T> Result<T> success(T data) {
        return Result.success(data);
    }

    /**
     * 创建成功响应（无数据）
     */
    protected Result<Void> success() {
        return Result.success();
    }

    /**
     * 创建失败响应
     */
    protected <T> Result<T> fail(String message) {
        return Result.fail(message);
    }

    /**
     * 创建失败响应
     */
    protected <T> Result<T> fail(ResultCode resultCode) {
        return Result.fail(resultCode);
    }

    /**
     * 创建失败响应
     */
    protected <T> Result<T> fail(int code, String message) {
        return Result.fail(code, message, null);
    }

    /**
     * 记录操作日志
     */
    protected void logOperation(String operation, Object... params) {
        log.info("执行操作: {} - 参数: {}", operation, params);
    }

    /**
     * 记录操作成功日志
     */
    protected void logSuccess(String operation, Object result) {
        log.info("操作成功: {} - 结果: {}", operation, result);
    }

    /**
     * 记录操作失败日志
     */
    protected void logFailure(String operation, String reason) {
        log.warn("操作失败: {} - 原因: {}", operation, reason);
    }
}
